package com.csproj.example.service;

import com.csproj.example.domain.Organization;
import com.csproj.example.repository.OrganizationRepository;
import com.csproj.example.service.dto.OrganizationDTO;
import com.csproj.example.service.mapper.OrganizationMapper;
import com.csproj.siiat.base.common.dto.BaseDTO;
import com.csproj.siiat.base.common.exception.BaseAppException;
import com.csproj.siiat.base.common.logback.Logback;
import com.csproj.siiat.base.common.util.CodeFactory;
import com.csproj.siiat.base.common.util.FileUtils;
import com.csproj.siiat.security.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Map;

/**
 * service样例
 * TODO save、saveAndGetDTO、update、updateAndGetDTO、delete、
 * TODO findAll、findAllAndGetDTO、findPageList、findPageListAndGetDTO、findOne、findOneAndGetDTO
 *
 * TODO @Transactional 事务注解
 * TODO @service 依赖注入
 */
@Service
@Transactional
public class OrganizationService {

    private final Logger log = LoggerFactory.getLogger(OrganizationService.class);

    @Resource(name = "organizationRepository")
    private OrganizationRepository organizationRepository;

    private OrganizationMapper organizationMapper;


    public OrganizationService(OrganizationMapper organizationMapper) {
        this.organizationMapper = organizationMapper;
    }

    /**
     * 保存机构并且返回前端需要发的dto，包括扩展属性createName
     * @param organizationDTO
     * @return organizationDTO
     * TODO 主要负责从前端接收值
     * TODO 其他业务方法，比如保存试卷时同时保存章节
     * TODO DTO的扩展属性，在此方法复制
     */
    public OrganizationDTO saveAndGetDTO(OrganizationDTO organizationDTO) {
        Organization organization = organizationMapper.toEntity(organizationDTO);
        organization = save(organization);
        organizationDTO = organizationMapper.toDto(organization);
        return organizationDTO;
    }

    /**
     * 保存机构
     * @param organization
     * @return organization
     * TODO 纯粹的保存方法，通用于所有保存业务调用
     * TODO 赋默认值，保存后，检查数据库，是否所有字段都有准确值
     */
    public Organization save(Organization organization) {
        Logback.warn(OrganizationService.class.toString(),"save","77",
            String.valueOf(organization.getName()),"备注", "高海洲", log);

        //生成编号和code码
        Integer currentNO = nextNO();
        String code = CodeFactory.createCode(currentNO,organization.getParentCode());
        organization.setCode(code);
        organization.setNo(currentNO);
        organization.setUpdateBy(SecurityUtils.getCurrentUserId());
        organization.updateDate(ZonedDateTime.now());
        organization.setCreateBy(SecurityUtils.getCurrentUserId());
        organization.setCreateDate(ZonedDateTime.now());
        organization.setDelFlag(0);
        return organizationRepository.save(organization);
    }

    /**
     * 保存机构
     * @param organizations
     * @return organization
     * TODO 纯粹的保存方法，通用于所有保存业务调用
     * TODO 赋默认值，保存后，检查数据库，是否所有字段都有准确值
     */
    public List<Organization> batchSave(List<Organization> organizations) {
        Integer currentNO = nextNO();
        for (int i = 0; i<organizations.size(); i++){
            Organization organization = organizations.get(i);
            currentNO = currentNO+1;
            //生成编号和code码
            String code = CodeFactory.createCode(currentNO,organization.getParentCode());
            organization.setCode(code);
            organization.setNo(currentNO);
            organization.setUpdateBy(SecurityUtils.getCurrentUserId());
            organization.updateDate(ZonedDateTime.now());
            organization.setCreateBy(SecurityUtils.getCurrentUserId());
            organization.setCreateDate(ZonedDateTime.now());
            organization.setDelFlag(0);
        }

        return organizationRepository.save(organizations);
    }

    /**
     * 修改机构并且返回前端需要发的dto，包括扩展属性
     * @param organizationDTO
     * @return organizationDTO
     * TODO 类似SAVE
     */
    public OrganizationDTO updateAndGetDTO(OrganizationDTO organizationDTO) throws BaseAppException {
        Organization organization = organizationRepository.findOne(organizationDTO.getId());
        if(organization == null){
            throw new BaseAppException(false,"id不存在");
        }
        organization.setName(organizationDTO.getName());
        organization.setType(organizationDTO.getType());
        organization = update(organization);
        return organizationMapper.toDto(organization);
    }

    /**
     * 修改机构
     * @param organization
     * @return organization
     * TODO 类似SAVE
     */
    public Organization update(Organization organization) {
        Organization organizationDB = findOne(organization.getId());
        organizationDB.setName(organization.getName());
        organizationDB.setType(organization.getType());
        organizationDB.setUpdateDate(ZonedDateTime.now());
        organizationDB.setUpdateBy(SecurityUtils.getCurrentUserId());
        organizationDB = organizationRepository.save(organizationDB);
        return organizationDB;
    }

    /**
     *  获取所有机构信息
     *  @return
     *  TODO 返回纯粹的数据库对象，不包含扩展属性，适用于所有调取业务方法
     */
    @Transactional(readOnly = true)
    public List<Organization> findAll() {
        List<Organization> organizations = organizationRepository.findAll();
        return organizations;
    }

    /**
     *  获取所有机构信息
     *  @return
     *  TODO 返回DTO，包含扩展属性
     *  TODO 如果扩展属性不同，可写多个findAllAndGetDTO1、findAllAndGetDTO2，注明扩展的属性
     */
    @Transactional(readOnly = true)
    public List<OrganizationDTO> findAllAndGetDTO() {
        List<OrganizationDTO> organizationDTOS = organizationMapper.toDto(findAll());
//        extendCreatName(organizationDTOS);
        return organizationDTOS;
    }

    /**
     *  获取所有机构信息（分页）
     *  @return the list of entities
     *
     *  TODO 返回纯粹的数据库对象，不包含扩展属性，适用于所有调取业务方法
     */
    @Transactional(readOnly = true)
    public Page<Organization> findPageList(Map<String, Object> map, Pageable pageable) {
        Page<Organization> result = organizationRepository.findPageList(map,pageable);
        return result;
    }

    /**
     *  获取所有机构信息（分页）
     *  @return the list of entities
     *
     *  TODO 返回DTO，包含扩展属性
     *  TODO 如果扩展属性不同，findPageListAndGetDTO1、findPageListAndGetDTO2，注明扩展的属性
     */
    @Transactional(readOnly = true)
    public BaseDTO findPageListAndGetDTO(Map<String,Object> map, Pageable pageable) {
        Page<Organization> result = findPageList(map,pageable);
        List<Organization> organizations = result.getContent();
        List<OrganizationDTO> organizationDTOs = organizationMapper.toDto(organizations);
        return BaseDTO.createBaseDTO(result).setFieldList(organizationDTOs);
    }


    /**
     * 根据id，获取机构信息
     *  @param id 主键id
     *  @return creator、questionTypeName
     *
     *  TODO 返回DTO，包含扩展属性
     *  TODO 如果扩展属性不同，findPageListAndGetDTO1、findPageListAndGetDTO2，注明扩展的属性
     */
    @Transactional(readOnly = true)
    public OrganizationDTO findOneAndGetDTO(String id) {
        Organization organization = findOne(id);
        OrganizationDTO organizationDTO = organizationMapper.toDto(organization);
        return organizationDTO;
    }

    /**
     * 根据id，获取机构信息
     *  @param id the id of the entity
     *  @return the entity
     *
     *  TODO 返回纯粹的数据库对象，不包含扩展属性，适用于所有调取业务方法
     */
    @Transactional(readOnly = true)
    public Organization findOne(String id) {
        Organization organization = organizationRepository.findOne(id);
        if(organization == null){
            throw new BaseAppException(false,"id有错误");
        }
        return organization;
    }

    /**
     *  根据id，删除机构信息
     *  @param id the id of the entity
     */
    public void delete(String id) {
        organizationRepository.delete(id);
    }

    /**
     * 根据机构ids，批量删除机构信息
     * @param ids
     */
    public void deleteIds(String[] ids){
        organizationRepository.deleteIds(ids);
    }

    /**
     * 上传文件
     * @param file
     */
    public String uploadFile(HttpServletRequest request, MultipartFile file){
        String filePath = FileUtils.excelUpload(request,file,File.separator+"upload"+ File.separator+"organization");
        return filePath;
    }

    /**
     * 生成机构的no
     * @author LM
     * @date 2017-5-23
     * @return Long
     */
    public Integer nextNO (){
        List<Organization> organizationList = organizationRepository.findAll();
        organizationList.sort((organization1,organization2) -> organization1.getNo().compareTo(organization2.getNo()));
        Integer orgSize = organizationList.size();
        Integer no;
        if (orgSize > 0) {
            Organization organization = organizationList.get(orgSize-1);
            no = organization.getNo() + 1;
        } else {
            no = 1;
        }
        return no;
    }
}
